Fix hiding popover when focus moves outside
authorPhillip Wood <phillip.wood@dunelm.org.uk>
Mon, 25 Apr 2016 12:16:21 +0000 (13:16 +0100)
committerMatthias Clasen <mclasen@redhat.com>
Mon, 6 Jun 2016 02:54:00 +0000 (22:54 -0400)
Commit a01fe14 changed the behaviour of popovers when the focus leaves
them to stop child popovers being hidden when the focus leaves their
parent. However they are now a bit too reluctant to hide - if the
focus passes to an unrelated popover the first popover is not
hidden. Also if the focus passes to another widget that does not
perform a gtk grab then the popover isn't hidden until the user
presses a non-movement key or clicks outside the popover.

The solution is to go back to checking if the focused widget is a
descendant of the popover, but to include popovers and their related
widgets in the ancestry chain.

https://bugzilla.gnome.org/show_bug.cgi?id=765595

gtk/gtkpopover.c

index 9c19fbb871079de3f1a5c5abf69eacb84fc3166f..8d170dd9b74d61c9fd84b9d64abd5fb5a64c1987 100644 (file)
@@ -439,17 +439,23 @@ window_set_focus (GtkWindow  *window,
 {
   GtkPopoverPrivate *priv = gtk_popover_get_instance_private (popover);
 
-  if (priv->modal && widget &&
-      gtk_widget_is_drawable (GTK_WIDGET (popover)) &&
-      !gtk_widget_is_ancestor (widget, GTK_WIDGET (popover)))
-    {
-      GtkWidget *grab_widget;
+  if (!priv->modal || !widget || !gtk_widget_is_drawable (GTK_WIDGET (popover)))
+    return;
 
-      grab_widget = gtk_grab_get_current ();
+  widget = gtk_widget_get_ancestor (widget, GTK_TYPE_POPOVER);
+  while (widget != NULL)
+    {
+      if (widget == GTK_WIDGET (popover))
+        return;
 
-      if (!grab_widget || !GTK_IS_POPOVER (grab_widget))
-        gtk_widget_hide (GTK_WIDGET (popover));
+      widget = gtk_popover_get_relative_to (GTK_POPOVER (widget));
+      if (widget == NULL)
+        break;
+      widget = gtk_widget_get_ancestor (widget, GTK_TYPE_POPOVER);
     }
+
+  popover_unset_prev_focus (popover);
+  gtk_widget_hide (GTK_WIDGET (popover));
 }
 
 static void